﻿/*
 * Author:		shikezheng
 * Create date: 2011-06-15
 * Description:	静态类。此类用于Model与Entity类型之间的转换
 * */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace YhmOA.Common
{
    public static class EntityModelConvert
    {
        /// <summary>
        /// 要忽略的属性类型名称
        /// </summary>
        public static List<String> ignoreEntityTypes = new List<String> {"AnonymousType0`1", "EntityReference`1", "EntityState", "EntityKey", "EntitySetName" };

        /// <summary>
        /// 扩展方法，将匿名集合转化为Model集合
        /// </summary>
        /// <typeparam name="T">Model类型</typeparam>
        /// <param name="entityList">匿名集合</param>
        /// <returns>Model集合</returns>
        public static List<T> ToModelListByAnonymous<T>(this List<Object> entityList)
        {
            List<T> modelList = new List<T>();
            try
            {
                foreach (Object item in entityList)
                {
                    Object newModel = Activator.CreateInstance(typeof(T));
                    item.ToModel(newModel);
                    modelList.Add((T)newModel);
                }
                
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message);
            }
            return modelList;
        }

        /// <summary>
        /// 扩展方法，将匿名类型转换为Model
        /// </summary>
        /// <param name="entity">匿名类型</param>
        /// <param name="model">Model</param>
        public static void ToModel(this Object entity, Object model)
        {
            try
            {
                Type entityType = entity.GetType();
                Type modelType = model.GetType();
                foreach (System.Reflection.PropertyInfo entityPro in entityType.GetProperties())
                {
                    if (entityPro.CanRead)
                    {
                        if (ignoreEntityTypes.Contains(entityPro.PropertyType.Name))
                        {
                            continue;
                        }
                        
                        System.Reflection.PropertyInfo modelPro =
                            modelType.GetProperty(entityPro.Name);
                        if (modelPro != null && modelPro.CanWrite)
                        {
                            modelPro.SetValue(model, entityPro.GetValue(entity, null), null);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message);
            }
        }

        /// <summary>
        /// 扩展方法，将匿名类型转换为Model
        /// </summary>
        /// <param name="entity">匿名类型</param>
        /// <param name="model">Model</param>
        /// <param name="ignorePro">要忽略的属性名称</param>
        public static void ToModel(this Object entity, Object model, string[] ignorePro)
        {
            try
            {
                Type entityType = entity.GetType();
                Type modelType = model.GetType();
                foreach (System.Reflection.PropertyInfo entityPro in entityType.GetProperties())
                {
                    if (entityPro.CanRead)
                    {
                        if (ignorePro.Contains(entityPro.Name.ToLower()))
                        {
                            continue;
                        }
                        if (ignoreEntityTypes.Contains(entityPro.PropertyType.Name))
                        {
                            continue;
                        }

                        System.Reflection.PropertyInfo modelPro =
                            modelType.GetProperty(entityPro.Name);
                        if (modelPro != null && modelPro.CanWrite)
                        {
                            modelPro.SetValue(model, entityPro.GetValue(entity, null), null);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message);
            }
        }
    }
}
